package com.example.springboot.web;

import com.example.springboot.bean.Notify;
import com.example.springboot.bean.NotifyStatus;
import com.example.springboot.bean.Result;
import com.example.springboot.bean.User;
import com.example.springboot.biz.BizException;
import com.example.springboot.biz.MailServiceImpl;
import com.example.springboot.biz.UserBiz;
import com.example.springboot.mapper.NotifyMapper;
import org.hibernate.validator.constraints.Length;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.validation.Errors;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.bind.support.SessionStatus;

import javax.annotation.Resource;
import javax.servlet.http.HttpSession;
import javax.validation.Valid;
import javax.validation.constraints.NotEmpty;
import javax.validation.constraints.NotNull;

@Controller
@SessionAttributes({"loginedUser", "forgetVcode"})
public class UserAction {

    @Resource
    private UserBiz ub;

    // 表单提交方式实现注册  VS  Ajax 提交方式
    @PostMapping("reg")
    public String reg(@Valid User user, Errors errors, Model model,
                      @SessionAttribute String regVcode,
                      String vcode) {

        if (vcode.equals(regVcode) == false) {
            errors.reject("vcode", "验证码错误!");
        }

        try {
            ub.reg(user, errors);
            return "login";
        } catch (BizException e) {
            e.printStackTrace();
            model.addAttribute("errors", e.getData());
        }
        return "reg";
    }

    @RequestMapping("to{page}")
    public String toPage(@PathVariable String page) {
        return page;
    }

    /**
     * Ajax 方法 用于发送注册验证码, 用于验证邮箱地址是否正确
     * AJAX 方法中 , 在会话对象中存放数据, 必须注入会话对象
     *
     * @SessionAttributes 这种方法在 ajax 方法中不能使用, ajax 不能使用 Model
     * @param email
     * @param session
     * @return
     */
    @Resource
    private MailServiceImpl smi;

    //AJAX
    @GetMapping("sendRegVcode")
    @ResponseBody
    public Result sendRegVcode(String email, HttpSession session) {
        String to = email;
        String subject = "注册验证码";
        // 获取时间戳字符串
        String vcode = System.currentTimeMillis() + "";
        // 截取后4位
        vcode = vcode.substring(vcode.length() - 4, vcode.length());
        String content = "注册新用户的验证码: " + vcode;
        try {
            smi.sendSimpleMail(to, subject, content);
            session.setAttribute("regVcode", vcode);
            return new Result(1, "验证码发送成功!", null);
        } catch (Exception e) {
            e.printStackTrace();
            return new Result(0, "验证码发送失败!", null);
        }
    }

    // 表单提交方式实现登录  VS  Ajax 提交方式  ==> 添加会话属性的区别
    @PostMapping("login")
    public String login(@Valid User user, Errors errors, Model model) {
        try {
            model.addAttribute("loginedUser", ub.login(user, errors));
            return "redirect:/";  // 响应重定向
        } catch (BizException e) {
            e.printStackTrace();
            model.addAttribute("errors", e.getData());
        }
        return "login";
    }

    @RequestMapping("forget")
    public String forget(@Valid User user, Errors errors, Model model) {
        try {
            User dbuser = ub.checkName(user, errors);
            String to = dbuser.getEmail();
            String subject = "重置密码验证码";
            // 获取时间戳字符串
            String vcode = System.currentTimeMillis() + "";
            // 截取后4位
            vcode = vcode.substring(vcode.length() - 4, vcode.length());
            String content = "重置密码新用户的验证码: " + vcode;
            try {
                smi.sendSimpleMail(to, subject, content);
                // 存入模型 ==> 存入会话
                model.addAttribute("forgetVcode", vcode);
            } catch (Exception e) {
                e.printStackTrace();
                errors.rejectValue("name", "emailError", "邮箱地址错误");
                throw new BizException("邮箱地址错误", errors.getAllErrors());
            }
            // 正确 跳转到输入密码的页面
            return "forget2";
        } catch (BizException e) {
            model.addAttribute("errors", e.getData());
            // 错误 返回原页面
            return "forget1";
        }
    }

    @PostMapping("resetPwd")
    public String resetPwd(@Valid User user, Errors errors, Model model,
                           @SessionAttribute String forgetVcode,
                           String vcode) {

        if (vcode.equals(forgetVcode) == false) {
            errors.reject("vcode", "验证码错误!");
        }

        try {
            ub.resetPwd(user, errors);
            return "login";
        } catch (BizException e) {
            e.printStackTrace();
            model.addAttribute("errors", e.getData());
        }
        return "forget2";
    }

    @RequestMapping("logout")
    public String logout(SessionStatus ss) {
        ss.setComplete();
        return "index";
    }

    @Resource
    private NotifyMapper nm;

    @RequestMapping("readNotify")
    @ResponseBody
    public Result readNotify(NotifyStatus notifyStatus,
                             @SessionAttribute(required = false) User loginedUser) {
        if (loginedUser == null) {
            return new Result(0, "请先登录系统", null);
        }
        notifyStatus.setUserId(loginedUser.getId());
        notifyStatus.setStatus(1);
        nm.insertStatus(notifyStatus);
        // 移除 用户对象 中已阅的公告通知
        for (int i = 0; i < loginedUser.getUnreads().size(); i++) {
            if(loginedUser.getUnreads().get(i).getId().equals(notifyStatus.getNotifyId())){
                loginedUser.getUnreads().remove(i);
                break;
            }
        }
        return new Result(1, "已阅成功!", null);
    }


}
